package com.coc.action;

import com.coc.bean.*;
import com.coc.bean.res.*;
import com.coc.bean.war.Camp;
import com.coc.bean.war.Tran;
import com.coc.bean.def.*;
import com.coc.dao.BuildSettingXML;
import com.coc.dao.Building;
import com.coc.dao.EloUserDAO;
import com.coc.dao.MemCachedDAO;
import com.coc.service.CocBattleService;
import com.coc.service.CocMapService;
import com.coc.service.CocUserService;
import com.coc.util.MemCacheUtil;
import com.coc.util.MemException;
import com.coc.util.PubFun;
import com.coc.util.SignException;
import com.schooner.MemCached.MemcachedItem;

import java.io.IOException;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Random;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.actions.DispatchAction;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class DataAction extends BaseAction {
	static Logger logger = Logger.getLogger(DataAction.class.getName());

	public ActionForward userinfo(ActionMapping mapping, ActionForm pcUserForm,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();
		try {
			CcMap cm = (CcMap) MemCacheUtil.getObject("cm_" + request.getParameter("id"));
			
			out.print("{\"token\":\"\"," + cm.toString() + "}");
		} catch (Exception e) {
			out.print("{\"error\":{\"value\":0}}");
			out.flush();
			out.close();
			e.printStackTrace();
		}
		return null;
	}
	
	public ActionForward del(ActionMapping mapping, ActionForm pcUserForm,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();
		try {
			for (int i = 1; i < 100; i++) {
				MemCacheUtil.delValue("cm_" + i);
			}

			return null;
		} catch (Exception e) {
			out.print("{\"error\":{\"value\":0}}");
			out.flush();
			out.close();
			e.printStackTrace();
		}
		return null;
	}

	public ActionForward test(ActionMapping mapping, ActionForm pcUserForm,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();
		try {
			String str = request.getParameter("str");
			if (str.equals("1")) {

				if (request.getSession().getAttribute("ttt") != null) {
					System.out.println("done");
					out.print("{\"error111\":{\"value\":" + str + "}}");
				} else {
					System.out.println("sleep");
					request.getSession().setAttribute("ttt", "ttt");
					test(mapping, pcUserForm, request, response);
				}
			} else {
				out.print("{\"error\":{\"value\":" + str + "}}");
			}
			return null;
		} catch (Exception e) {
			out.print("{\"error\":{\"value\":0}}");
			out.flush();
			out.close();
			e.printStackTrace();
		}
		return null;
	}

	public ActionForward reg(ActionMapping mapping, ActionForm pcUserForm,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();
		try {
			String openid = request.getParameter("openid");
			String name = request.getParameter("name");
			CcEloUser ceu = getEloUserDAO().findBySNSName(name);
			// "map":{"T1":["6,6","14,21","4,36","31,20"],"T2":["5,25","8,22","20,8"],
			// "T3":["13,4","25,37"],"T4":["5,3","3,8","4,12","14,28","14,36","22,31","35,25"]
			// ,"T5":["24,34","26,34","25,29","19,3"],
			// "T6":["7,9","4,16","4,28","19,35","31,27","36,17","33,12","28,3"],
			// "T7":["12,8","33,32"],"T8":["30,9","23,29","22,33","23,36"]
			// ,"T9":["28,33","3,32","9,31","4,20","34,20","25,9"],"T10":["23,6","9,16","27,28"]
			// ,"T11":["8,3","13,17","12,30","6,34","27,30","34,4"]
			// ,"SLAV":["24,25"],"HALL":"23,20,1,0","BARK":["20,22,1,0"],"CAMP":["17,11,1,0"],"GOLS":["16,19,1,0"],"ELXS":["20,18,1,0"],"GOLM":["24,13,1,0"],"ELXM":["28,17,1,0"]}

			if (ceu == null) {
				ceu = new CcEloUser();
				ceu.setSnsid(openid);
				ceu.setHtlv(2);
				ceu.setName(name);
				getEloUserDAO().saveOrUpdate(ceu);
				CcMap cm = new CcMap();
				cm.setUid(Integer.valueOf(ceu.getId()));
				CcUser cu = new CcUser();
				cu.setQqp(227);
				cu.setHtlv(2);
				cu.setId(Integer.valueOf(ceu.getId()));
				cu.setSnsname(name);
				cu.setSnsid(openid);
				cu.setGold(Integer.valueOf(1000));
				cu.setElixir(Integer.valueOf(1000));
				cu.setGem(Integer.valueOf(500));
				cm.setCcuser(cu);
				// 添加一个2本基地,1个工人,一个cann,一个golm,elxm,gols,elxs,bark,camp
				Hall tmp = new Hall();
				tmp.setUpgradeEnd(0);
				tmp.setLv(2);
				tmp.setX(23);
				tmp.setY(20);
				cm.setHall(tmp);
				cm.setTotalUnitSize(cm.getTotalUnitSize() + 4 * 4);
				Slav slav = new Slav();
				slav.setX(24);
				slav.setY(25);
				List list = new ArrayList();
				list.add(slav);
				cm.setSlavs(list);
				cm.setTotalUnitSize(cm.getTotalUnitSize() + 2 * 2);
				Cann cann = new Cann();
				cann.setX(23);
				cann.setY(16);
				cann.setLv(1);
				list = new ArrayList();
				list.add(cann);
				cm.setCanns(list);
				cm.setTotalUnitSize(cm.getTotalUnitSize() + 3 * 3);
				Golm golm = new Golm();
				golm.setLv(1);
				golm.setLefttime(System.currentTimeMillis());
				golm.setX(24);
				golm.setY(13);
				list = new ArrayList();
				list.add(golm);
				cm.setGolms(list);
				cm.setTotalUnitSize(cm.getTotalUnitSize() + 3 * 3);
				Elxm elxm = new Elxm();
				elxm.setLv(1);
				elxm.setLefttime(System.currentTimeMillis());
				elxm.setX(28);
				elxm.setY(17);
				list = new ArrayList();
				list.add(elxm);
				cm.setElxms(list);
				cm.setTotalUnitSize(cm.getTotalUnitSize() + 3 * 3);
				Elxs elxs = new Elxs();
				elxs.setLv(1);
				elxs.setX(20);
				elxs.setY(18);
				list = new ArrayList();
				list.add(elxs);
				cm.setElxss(list);
				Gols gols = new Gols();
				gols.setLv(1);
				gols.setX(16);
				gols.setY(19);
				list = new ArrayList();
				list.add(gols);
				cm.setGolss(list);

				cm.setTotalUnitSize(cm.getTotalUnitSize() + 3 * 3);
				Tran bark = new Tran();
				bark.setX(20);
				bark.setY(22);
				bark.setLv(1);
				list = new ArrayList();
				list.add(bark);
				cm.setBarks(list);

				cm.setTotalUnitSize(cm.getTotalUnitSize() + 3 * 3);
				Camp camp = new Camp();
				camp.setX(17);
				camp.setY(11);
				camp.setLv(1);
				list = new ArrayList();
				list.add(camp);
				cm.setCamps(list);

				cm.setTotalUnitSize(cm.getTotalUnitSize() + 3 * 3);
				// T6,7,11 size=3
				// T1":["6,6","14,21","4,36","31,20"],
				Hashtable<String, List<Tree>> trees = new Hashtable<String, List<Tree>>();

				List<Tree> treeList = new ArrayList<Tree>();
				Tree tree = new Tree();
				tree.setX(6);
				tree.setY(6);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(14);
				tree.setY(21);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(4);
				tree.setY(36);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(31);
				tree.setY(20);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				trees.put("T1", treeList);
				// T2":["5,25","8,22","20,8"],
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(5);
				tree.setY(25);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(8);
				tree.setY(22);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(20);
				tree.setY(8);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				trees.put("T2", treeList);
				// T3"::["13,4","25,37"]
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(13);
				tree.setY(4);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(25);
				tree.setY(37);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				trees.put("T3", treeList);
				// T4":":["5,3","3,8","4,12","14,28","14,36","22,31","35,25"],
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(5);
				tree.setY(3);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(3);
				tree.setY(8);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(4);
				tree.setY(12);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				// ==
				tree = new Tree();
				tree.setX(14);
				tree.setY(28);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(14);
				tree.setY(36);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(22);
				tree.setY(31);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(35);
				tree.setY(25);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				trees.put("T4", treeList);
				// T5":["24,34","26,34","25,29","19,3"]
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(24);
				tree.setY(34);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(26);
				tree.setY(34);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(25);
				tree.setY(29);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(19);
				tree.setY(3);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				trees.put("T5", treeList);
				// "T6":["7,9","4,16","4,28","19,35","31,27","36,17","33,12","28,3"],
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(7);
				tree.setY(9);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(4);
				tree.setY(16);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(4);
				tree.setY(28);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(19);
				tree.setY(35);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(31);
				tree.setY(27);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(36);
				tree.setY(17);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(33);
				tree.setY(12);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(28);
				tree.setY(3);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				trees.put("T6", treeList);
				// T7":["12,8","33,32"]
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(12);
				tree.setY(8);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(33);
				tree.setY(32);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				trees.put("T7", treeList);
				// "T8":["30,9","23,29","22,33","23,36"],
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(30);
				tree.setY(9);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(23);
				tree.setY(29);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(22);
				tree.setY(33);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(23);
				tree.setY(36);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				trees.put("T8", treeList);
				// "T9":["28,33","3,32","9,31","4,20","34,20","25,9"]
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(28);
				tree.setY(33);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(3);
				tree.setY(32);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(9);
				tree.setY(31);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(4);
				tree.setY(20);
	
				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(34);
				tree.setY(20);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(25);
				tree.setY(9);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				trees.put("T9", treeList);
				// "T10":["23,6","9,16","27,28"]
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(23);
				tree.setY(6);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(9);
				tree.setY(16);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(27);
				tree.setY(28);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 2 * 2);
				treeList.add(tree);
				trees.put("T10", treeList);
				// "T11":["8,3","13,17","12,30","6,34","27,30","34,4"]
				treeList = new ArrayList<Tree>();
				tree = new Tree();
				tree.setX(8);
				tree.setY(3);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(13);
				tree.setY(17);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(12);
				tree.setY(30);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(6);
				tree.setY(34);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(27);
				tree.setY(30);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				tree = new Tree();
				tree.setX(34);
				tree.setY(4);

				cm.setTotalTreeSize(cm.getTotalUnitSize() + 3 * 3);
				treeList.add(tree);
				trees.put("T11", treeList);
				cm.setTrees(trees);
				MemCacheUtil.addObject("cm_" + cm.getUid(), cm);
				out.print("{\"sign\":{\"value\":" + cm.getUid() + "}}");
			} else {
				out.print("{\"sign\":{\"value\":0}}");
			}

			return null;
		} catch (Exception e) {
			out.print("{\"error\":{\"value\":0}}");
			out.flush();
			out.close();
			e.printStackTrace();
		}
		return null;
	}

	public ActionForward gmlogin(ActionMapping mapping, ActionForm pcUserForm,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();
		try {
			// String uid = request.getParameter("uid");
			String plant  = "";
			String openid = request.getParameter("openid");
			String pass = request.getParameter("password");
			// CcEloUser ceu = getEloUserDAO().findByID(Integer.parseInt(uid));
			if (openid.equals("aaaaa")) {
				if (!pass.equals("a111a")) {
					out.print("{\"sign\":{\"value\":-1}}");
					return null;
				}

			} else if (openid.equals("bbbbb")) {
				if (!pass.equals("b222b")) {
					out.print("{\"sign\":{\"value\":-1}}");
					return null;
				}
			} else if (openid.equals("ccccc")) {
				if (!pass.equals("c333c")) {
					out.print("{\"sign\":{\"value\":-1}}");
					return null;
				}
			} else {
				out.print("{\"sign\":{\"value\":-1}}");
				return null;
			}
			CcEloUser ceu = getEloUserDAO().findBySNSID(openid);
			if (ceu != null) {
				CcMap cm = (CcMap) MemCacheUtil.getObject("cm_" + ceu.getId());
				// 当前地图能生成的树总量
				// 注意生成树改成客户端生成,上报坐标,所以最后生成日期和totalTreeSize在上报接口中更新
				int treemax = (1600 - cm.getTotalUnitSize()) / 50
						- cm.getTotalTreeSize(); 
				// 生成间隔10个小时 
				// int treetime =36000000;
				long treetime = System.currentTimeMillis() - ceu.getLasttree(); 
				// 本次理论数量
				int treecount = (int) (treetime / 3600000L);
			
				// 数量大于0才开始判断,循环生成
				if (treecount > 0) {
					if (treecount > treemax) {
						treecount = treemax;
					} // 大于3随机加减1-2
					if (treecount > 3) {
						treecount = treecount + (new Random().nextInt(5) - 2);
					} 
					// 循环,先随机出是什么tree
					for (int i = 0; i < treecount; i++) {
						Building bu = this.getBuildSettingXML()
								.findRandomTree();
						if(plant.length()==0){
							plant=bu.getType();
						}else{
							plant=plant+","+bu.getType();
						}
					}
				}
				// 保存2个副本,给后续sign2回滚使用
				// 暂时取消
				// MemCacheUtil.setObject("cm_bak_"+ceu.getId(), cm);
				// MemCacheUtil.setObject("ceu_bak_"+ceu.getId(), ceu);
				String token = MD5digest(
						cm.getUid() + "|" + System.currentTimeMillis())
						.substring(8, 24);
				ceu.setLastaction(System.currentTimeMillis());
				ceu.setLastlogin(System.currentTimeMillis());
				getEloUserDAO().saveOrUpdate(ceu);
				// 把token存入memcached,代替保存session
				MemCacheUtil.setSession(cm.getUid().intValue(), token);
				String tk = cm.getUid() + "_" + token;
				out.print("{\"token\":\"" + tk + "\",\"plant \":\""+plant+"\"," + cm.toString() + "}");
			} else {
				out.print("{\"sign\":{\"value\":0}}");
			}
			MemCacheUtil.setObject("map_act_" + ceu.getId(), System.currentTimeMillis() + "");
			return null;
		} catch (Exception e) {
			out.print("{\"error\":{\"value\":0}}");
			out.flush();
			out.close();
			e.printStackTrace();
		}
		return null;
	}

	// 把一系列 act 打包在一起，集中发送的 HTTP 请求
	// 【注意】 只有【无返回值】的 act，才能被打包
	// &map_acts =
	// [{t:1469400255523,b:"LABT|0",a:"move",x:3,y:7},
	// {t:1469400235386,b:"BARK|2",a:"boost_upgrade"},....]
	// 全部service方法都接收2个参数,request和hashtable
	// 单独调用时候传request,打包时候把request中内容打包成hashtable
	public ActionForward map_acts(ActionMapping mapping, ActionForm pcUserForm,
			HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();
		StringBuffer sbf = new StringBuffer();

		if (!isLoginV(request)) {
			out.print("{\"error\":{\"type\":\"v\",\"value\":1}}");
			return null;
		}
		if (!isLogin(request)) {
			out.print("{\"error\":{\"value\":1}}");
			return null;
		}
		int id = Integer.parseInt(request.getParameter("tk").substring(0,
				request.getParameter("tk").indexOf("_")));
		long curlastact = Long.parseLong(request.getParameter("lastact")); // 本次打包方法中最后动作时间
		long casUnique = 0L;// --db中记录
		long lastact = 0L; // --db中记录
		// map_act_XXXXXX
		try {
			MemcachedItem mi = MemCacheUtil.getsObject("map_act_" + id);

			if (mi != null) {
				casUnique = mi.getCasUnique();
				lastact = (Long) mi.getValue();
			}
			// 负数说明处理中,等1秒继续递归调用
			if (lastact < 0) {
				logger.warn("UID:" + id + " map_acts sleep 1s...");
				Thread.sleep(1000L);
				map_acts(mapping, pcUserForm, request, response);
			}
			// 实际处理的动作包最后实际大等于当前包,
			// 当前包全是过期请求,抛弃并且返回sign1
			if (curlastact <= lastact) {
				logger.warn("expire map_acts  uid:" + id + " ...");
				out.print("{\"sign\":{\"value\":\"" + 1 + "\"}}");
				return null;
			}
			// 抢锁,并把curlastact置为负数
			// 如果抢锁失败等1秒继续递归调用(异常捕获处理)
			if (casUnique > 0) {
				MemCacheUtil.setObject("map_act_" + id, -1 * curlastact);
			} else {
				MemCacheUtil.casObject("map_act_" + id, -1 * curlastact,
						casUnique);
			}
			// &map_acts =
			// [{t:1469400255523,b:"LABT|0",a:"move",x:3,y:7},
			// {t:1469400235386,b:"BARK|2",a:"boost_upgrade"},....]
			JSONArray ja = this.getMethodArray(request);
			if (ja != null) {
				for (int i = 0; i < ja.size(); i++) {
					JSONObject jo = (JSONObject) ja.get(i);
					String act = jo.getString("a");
					if (act.equals("build")) {
						getCocMapService().MapBuild(request, jo);
					} else if (act.equals("upgrade")) {
						getCocMapService().MapUpgrade(request, jo);
					} else if (act.equals("move")) {
						getCocMapService().MapMove(request, jo);
					} else if (act.equals("sell")) {
						getCocMapService().MapSell(request, jo);
					} else if (act.equals("remove")) {
						getCocMapService().MapCut(request, jo);
					} else if (act.equals("collect")) {
						getCocUserService().Collect(request, jo);
					} else if (act.equals("train")) {
						getCocUserService().Tran(request, jo);
					} else if (act.equals("spell")) {
						getCocUserService().SpellResearch(request, jo);
					} else if (act.equals("lab")) {
						getCocUserService().LabResearch(request, jo);
					} else if (act.equals("lab_get")) {
						getCocUserService().LabGet(request, jo);
					} else if (act.equals("lab_cancel")) {
						getCocUserService().LabCancel(request, jo);
					} else if (act.equals("cancel_upgrade")) {
						getCocMapService().MapCancel(request, jo);
					} else if (act.equals("cancel_train")) {
						getCocUserService().CancelTran(request, jo);
					} else if (act.equals("cancel_spell")) {
						getCocUserService().CancelSpellResearch(request, jo);
					} else if (act.equals("boost_upgrade")) {
						getCocMapService().MapBoost(request, jo);
					} else if (act.equals("boost_train")) {
						getCocUserService().TranBoost(request, jo);
					} else if (act.equals("boost_spell")) {
						getCocUserService().SpellBoost(request, jo);
					} else if (act.equals("boost_lab")) {
						getCocUserService().LabBoost(request, jo);
					} else if (act.equals("boost_mine")) {
						getCocUserService().MineBoost(request, jo);
					}

				}
			}
			out.print("{\"sign\":{\"value\":\"" + 1 + "\"}}");
			// 完全成功后吧map_act_id 设置成正数
			MemCacheUtil.setObject("map_act_" + id, curlastact);
			return null;
		} catch (SignException se) {
			// sign错误2:作弊 用login时候缓存的数据回滚
			// 回滚暂时取消
			// if (se.getSign() == 2) {
			// CcMap cm = (CcMap) MemCacheUtil.getObject("cm_bak_" + id);
			// CcEloUser ceu = (CcEloUser) MemCacheUtil.getObject("ceu_bak_" +
			// id);
			// MemCacheUtil.setObject("cm_" + id, cm);
			// getEloUserDAO().saveOrUpdate(ceu);
			// }
			logger.warn("Find sign 2 uid:" + id + " reason:" + se.getMessage());
			// 2） 作弊后的“清理 token”, 清理成 0000
			MemCacheUtil.setSession(id, "0000");
			sbf.append("{\"sign\":{\"value\":" + se.getSign()
					+ "},\"reason\":\"" + se.getMessage() + "\"}");
			out.flush();
			out.close();
			// se.printStackTrace();
		} catch (MemException me) {
			// cas错误,没保存成功
			logger.warn("Find cas error uid:" + id + " reason:"
					+ me.getMessage());
			if (me.getMem_sign() == 0) {
				CcMap cm = (CcMap) MemCacheUtil.getObject("cm_bak_" + id);
				CcEloUser ceu = (CcEloUser) MemCacheUtil.getObject("ceu_bak_"
						+ id);
				MemCacheUtil.setObject("cm_" + id, cm);
				getEloUserDAO().saveOrUpdate(ceu);
			}
			// me.printStackTrace();
		} catch (Exception e) {
			out.print("{\"error\":{\"value\":0}}");
			out.flush();
			out.close();
			e.printStackTrace();
		}
		return null;
	}

	// 匹配pvp
	public ActionForward pvp_match(ActionMapping mapping,
			ActionForm pcUserForm, HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		PrintWriter out = response.getWriter();
		StringBuffer sbf = new StringBuffer();
		try {
			if (!isLoginV(request)) {
				out.print("{\"error\":{\"type\":\"v\",\"value\":1}}");
				return null;
			}
			if (!isLogin(request)) {
				out.print("{\"error\":{\"value\":1}}");
				return null;
			}
			getCocBattleService().GetEloMatch(request, sbf);
			out.println(sbf.toString());
			return null;
		} catch (Exception e) {
			out.print("{\"error\":{\"value\":0}}");
			out.flush();
			out.close();
			e.printStackTrace();
		}
		return null;
	}
}
